# Contributor: Sergei Lukin <sergej.lukin@gmail.com>
# Contributor: Valery Kartel <valery.kartel@gmail.com>
# Contributor: Jakub Jirutka <jakub@jirutka.cz>
# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
pkgname=qemu
pkgver=9.1.1
pkgrel=1
pkgdesc="QEMU is a generic machine emulator and virtualizer"
url="https://qemu.org/"
arch="all"
license="GPL-2.0-only AND LGPL-2.1-only"
makedepends="
	alsa-lib-dev
	bash
	bison
	capstone-dev
	curl-dev
	flex
	glib-dev
	glib-static
	gnutls-dev
	gtk+3.0-dev
	libaio-dev
	libbpf-dev
	libcap-dev
	libcap-ng-dev
	libjpeg-turbo-dev
	libnfs-dev
	libpng-dev
	libseccomp-dev
	libslirp-dev
	libssh-dev
	liburing-dev
	libusb-dev
	libxml2-dev
	linux-headers
	lzo-dev
	meson
	ncurses-dev
	numactl-dev
	perl
	pulseaudio-dev
	py3-sphinx
	py3-sphinx_rtd_theme
	python3
	sdl2-dev
	snappy-dev
	spice-dev
	texinfo
	usbredir-dev
	util-linux-dev
	vde2-dev
	virglrenderer-dev
	vte3-dev
	xfsprogs-dev
	zlib-dev
	zlib-static
	zstd-dev
	"
pkggroups="qemu"
install="$pkgname.pre-install $pkgname.post-install $pkgname.pre-upgrade"

# suid needed for qemu-bridge-helper
# strip fails on .img files
# some tests does not run on our builders
options="suid !strip !check textrels"

subpackages="
	$pkgname-dev
	$pkgname-doc
	$pkgname-lang
	$pkgname-guest-agent:guest
	$pkgname-guest-agent-openrc
	$pkgname-tools:_tools
	$pkgname-hppa-firmware:_hppa_firmware
	$pkgname-ppc-firmware:_ppc_firmware
	$pkgname-s390x-firmware:_s390x_firmware
	$pkgname-pr-helper:_pr_helper
	$pkgname-vhost-user-gpu:_vhost_user_gpu
	$pkgname-bridge-helper:bridgehelper
	"

_subsystems="
	aarch64
	aarch64_be
	alpha
	arm
	armeb
	cris
	hexagon
	hppa
	i386
	loongarch64
	m68k
	microblaze
	microblazeel
	mips
	mips64
	mips64el
	mipsel
	mipsn32
	mipsn32el
	or1k
	ppc
	ppc64
	ppc64le
	riscv32
	riscv64
	s390x
	sh4
	sh4eb
	sparc
	sparc32plus
	sparc64
	system-aarch64
	system-alpha
	system-arm
	system-avr
	system-cris
	system-hppa
	system-i386
	system-loongarch64
	system-m68k
	system-microblaze
	system-microblazeel
	system-mips
	system-mips64
	system-mips64el
	system-mipsel
	system-or1k
	system-ppc
	system-ppc64
	system-riscv32
	system-riscv64
	system-rx
	system-s390x
	system-sh4
	system-sh4eb
	system-sparc
	system-sparc64
	system-tricore
	system-x86_64
	system-xtensa
	system-xtensaeb
	x86_64
	xtensa
	xtensaeb
	"
for _sub in $_subsystems; do
	subpackages="$subpackages $pkgname-$_sub:_subsys"
done

_modules="
	audio-alsa
	audio-oss
	audio-pa
	audio-sdl
	audio-spice
	block-curl
	block-dmg-bz2
	block-nfs
	block-ssh
	chardev-spice
	hw-display-qxl
	hw-display-virtio-gpu
	hw-display-virtio-gpu-gl
	hw-display-virtio-gpu-pci
	hw-display-virtio-gpu-pci-gl
	hw-display-virtio-vga
	hw-display-virtio-vga-gl
	hw-s390x-virtio-gpu-ccw
	hw-usb-host
	hw-usb-redirect
	ui-curses
	ui-egl-headless
	ui-gtk
	ui-opengl
	ui-sdl
	ui-spice-app
	ui-spice-core
	"

case "$CARCH" in
x86)
	# ui-dbus has textrels
	_configure_dbus=--disable-dbus-display
	;;
*)
	_modules="$_modules audio-dbus ui-dbus"
	_configure_dbus=--enable-dbus-display
	;;
esac

case "$CARCH" in
arm*|x86) ;;
*)
	makedepends="$makedepends ceph-dev"
	_modules="$_modules block-rbd"
	_configure_rbd="--enable-rbd"
	;;
esac

case "$CARCH" in
armv7|aarch64)
	makedepends="$makedepends xen-dev"
	_configure_xen="--enable-xen"
	;;
x86_64)
	makedepends="$makedepends xen-dev"
	_configure_xen="--enable-xen --enable-xen-pci-passthrough"
	;;
*)
	_configure_xen="--disable-xen"
	;;
esac


for _mod in $_modules; do
	subpackages="$subpackages $pkgname-$_mod:_module"
done
subpackages="$subpackages qemu-modules:_all_modules"

subpackages="$subpackages $pkgname-img"  # -img must be declared the last

source="https://download.qemu.org/qemu-$pkgver.tar.xz
	0006-linux-user-signal.c-define-__SIGRTMIN-MAX-for-non-GN.patch
	xattr_size_max.patch
	MAP_SYNC-fix.patch
	fix-sockios-header.patch
	guest-agent-shutdown.patch
	lfs64.patch
	musl-initialise-msghdr.patch
	fix-strerrorname_np.patch
	liburing.patch
	0001-util-util-cpuinfo-riscv.c-fix-riscv64-build-on-musl-.patch

	$pkgname-guest-agent.confd
	$pkgname-guest-agent.initd
	80-kvm.rules
	bridge.conf
	"

# secfixes:
#   8.0.2-r1:
#     - CVE-2023-2861
#   8.0.0-r6:
#     - CVE-2023-0330
#   7.1.0-r4:
#     - CVE-2022-2962
#     - CVE-2022-3165
#   7.0.0-r0:
#     - CVE-2021-4158
#   6.1.0-r0:
#     - CVE-2020-35503
#     - CVE-2021-3507
#     - CVE-2021-3544
#     - CVE-2021-3545
#     - CVE-2021-3546
#     - CVE-2021-3682
#   6.0.0-r2:
#     - CVE-2020-35504
#     - CVE-2020-35505
#     - CVE-2020-35506
#     - CVE-2021-3527
#   6.0.0-r1:
#     - CVE-2021-20181
#     - CVE-2021-20255
#     - CVE-2021-3392
#     - CVE-2021-3409
#     - CVE-2021-3416
#   5.2.0-r0:
#     - CVE-2020-24352
#     - CVE-2020-25723
#     - CVE-2020-25742
#     - CVE-2020-25743
#     - CVE-2020-27661
#     - CVE-2020-27821
#     - CVE-2020-29443
#     - CVE-2020-35517
#     - CVE-2021-20203
#   5.1.0-r1:
#     - CVE-2020-13361
#     - CVE-2020-13362
#     - CVE-2020-14364
#     - CVE-2020-15863
#     - CVE-2020-16092
#     - CVE-2020-17380
#     - CVE-2020-25084
#     - CVE-2020-25085
#     - CVE-2020-25624
#     - CVE-2020-25625
#     - CVE-2020-25741
#     - CVE-2020-28916
#   5.0.0-r0:
#     - CVE-2020-13659
#     - CVE-2020-13754
#     - CVE-2020-13791
#     - CVE-2020-13800
#     - CVE-2020-14415
#     - CVE-2020-15469
#     - CVE-2020-15859
#     - CVE-2020-27616
#     - CVE-2020-27617
#     - CVE-2021-20221
#   4.2.0-r0:
#     - CVE-2020-13765
#   2.8.1-r1:
#     - CVE-2016-7994
#     - CVE-2016-7995
#     - CVE-2016-8576
#     - CVE-2016-8577
#     - CVE-2016-8578
#     - CVE-2016-8668
#     - CVE-2016-8909
#     - CVE-2016-8910
#     - CVE-2016-9101
#     - CVE-2016-9102
#     - CVE-2016-9103
#     - CVE-2016-9104
#     - CVE-2016-9105
#     - CVE-2016-9106
#     - CVE-2017-2615
#     - CVE-2017-2620
#     - CVE-2017-5525
#     - CVE-2017-5552
#     - CVE-2017-5578
#     - CVE-2017-5579
#     - CVE-2017-5667
#     - CVE-2017-5856
#     - CVE-2017-5857
#     - CVE-2017-5898
#     - CVE-2017-5931

_compile_common() {
	"$builddir"/configure \
		--prefix=/usr \
		--localstatedir=/var \
		--sysconfdir=/etc \
		--libexecdir=/usr/lib/qemu \
		--python=/usr/bin/python3 \
		--disable-glusterfs \
		--disable-debug-info \
		--disable-bsd-user \
		--disable-werror \
		--enable-kvm \
		--enable-seccomp \
		--cc="${CC:-gcc}" \
		"$@"
	make ARFLAGS="rc"
}

build() {
	# it pretty much never makes sense to optimise qemu for disk size
	export CFLAGS="$CFLAGS -O2"
	export CXXFLAGS="$CXXFLAGS -O2"
	export CPPFLAGS="$CPPFLAGS -O2"

	mkdir -p "$builddir"/build \
		"$builddir"/build-static

	cd "$builddir"/build-static
	_compile_common \
		--enable-linux-user \
		--disable-system \
		--static \
		--disable-brlapi \
		--disable-bpf \
		--disable-cap-ng \
		--disable-capstone \
		--disable-curl \
		--disable-curses \
		--disable-docs \
		--disable-gcrypt \
		--disable-gnutls \
		--disable-gtk \
		--disable-guest-agent \
		--disable-guest-agent-msi \
		--disable-libnfs \
		--disable-mpath \
		--disable-nettle \
		--disable-numa \
		--disable-sdl \
		--disable-spice \
		--disable-tools

	cd "$builddir"/build
	_compile_common \
		--disable-linux-user \
		--audio-drv-list=oss,alsa,sdl,pa \
		--enable-bpf \
		--enable-cap-ng \
		--enable-capstone \
		--enable-curl \
		--enable-curses \
		--enable-docs \
		--enable-gtk \
		--enable-guest-agent \
		--enable-libnfs \
		--enable-libssh \
		--enable-linux-aio \
		--enable-lzo \
		--enable-modules \
		--enable-numa \
		--enable-pie \
		--enable-sdl \
		--enable-snappy \
		--enable-spice \
		--enable-tpm \
		--enable-usb-redir \
		--enable-vde \
		--enable-vhost-net \
		--enable-virglrenderer \
		--enable-virtfs \
		--enable-vnc \
		--enable-vnc-jpeg \
		--enable-zstd \
		$_configure_rbd \
		$_configure_dbus \
		$_configure_xen
}

check() {
	cd "$builddir"/build

	# XXX: ESSIV crypto tests are disabled, see test-crypto-ivgen-skip-essiv.patch.
	make check V=1
}

package() {
	cd "$builddir"/build-static
	make DESTDIR="$pkgdir" install

	cd "$builddir"/build
	make DESTDIR="$pkgdir" install

	install -Dm640 -g qemu "$srcdir"/bridge.conf \
		"$pkgdir"/etc/qemu/bridge.conf

	install -Dm644 "$srcdir"/80-kvm.rules \
		"$pkgdir"/usr/lib/udev/rules.d/80-kvm.rules

	# qemu-bridge-helper needs suid to create tunX devices;
	# allow only users in the qemu group to run it.
	chmod 04710 "$pkgdir"/usr/lib/qemu/qemu-bridge-helper
	chgrp qemu "$pkgdir"/usr/lib/qemu/qemu-bridge-helper

	# Do not install HTML docs.
	rm -rf "$pkgdir"/usr/share/doc
	# remove accel-qtest-* modules, not needed for package
	rm -f "$pkgdir"/usr/lib/qemu/accel-qtest-*

	install -Dm755 "$srcdir"/$pkgname-guest-agent.initd \
		"$pkgdir"/etc/init.d/$pkgname-guest-agent
	install -Dm644 "$srcdir"/$pkgname-guest-agent.confd \
		"$pkgdir"/etc/conf.d/$pkgname-guest-agent
}

_subsys() {
	local name=${1:-"${subpkgname#"$pkgname"-}"}
	pkgdesc="Qemu ${name/-/ } emulator"
	options=""
	depends=""
	case "$name" in
		system*) depends="qemu";;
	esac

	amove /usr/bin/qemu-$name

	local _arch=${name#system-}
	case "$name" in
		system-aarch64)
			amove /usr/share/qemu/edk2-aarch64-code.fd
			;;
		system-arm)
			amove /usr/share/qemu/edk2-arm-code.fd \
				/usr/share/qemu/edk2-arm-vars.fd
			;;
		system-x86_64|system-i386)
			provides="qemu-accel-tcg-$_arch"
			amove /usr/lib/qemu/accel-tcg-$_arch.so \
				/usr/share/qemu/edk2-$_arch-code.fd \
				/usr/share/qemu/edk2-$_arch-secure-code.fd
			;;
		system-s390x|system-hppa|system-ppc)
			depends="$pkgname-$_arch-firmware"
			;;
	esac
}

_tools() {
	pkgdesc="QEMU support tools"
	depends=""
	options=""
	amove /usr/bin/qemu-edid \
		/usr/bin/qemu-keymap \
		/usr/bin/elf2dmp
}

# keep s390x boot files in subpackage to prevent abuild from stripping it
_s390x_firmware() {
	pkgdesc="QEMU s390x boot devices"
	depends=""
	amove /usr/share/qemu/s390-ccw.img \
		/usr/share/qemu/s390-netboot.img
}

_hppa_firmware() {
	pkgdesc="QEMU hppa firmware"
	depends=""
	amove /usr/share/qemu/hppa-firmware.img
}

_ppc_firmware() {
	pkgdesc="QEMU ppc firmware"
	depends=""
	amove /usr/share/qemu/openbios-ppc
}

_vhost_user_gpu() {
	pkgdesc="QEMU vhost user GPU device"
	depends=""
	options=""
	amove /usr/lib/qemu/vhost-user-gpu \
		/usr/share/qemu/vhost-user/50-qemu-gpu.json
}

_pr_helper() {
	pkgdesc="QEMU pr helper utility"
	amove /usr/bin/qemu-pr-helper
}

img() {
	pkgdesc="QEMU command line tool for manipulating disk images"
	depends=""
	options=""

	mkdir -p "$subpkgdir"/usr/bin
	mv "$pkgdir"/usr/bin/qemu-img \
		"$pkgdir"/usr/bin/qemu-io \
		"$pkgdir"/usr/bin/qemu-nbd \
		"$pkgdir"/usr/bin/qemu-storage-daemon \
		"$subpkgdir"/usr/bin/

	# We exploit the fact that -img subpackage are created last
	# and check that we done have new systems that belongs in
	# subpackage.
	local path= retval=0
	for path in "$pkgdir"/usr/bin/qemu-system-* "$pkgdir"/usr/lib/qemu/*.so; do
		if [ -r "$path" ]; then
			error "Please create a subpackage for ${path##*/}"
			retval=1
		fi
	done
	return $retval
}

guest() {
	pkgdesc="QEMU guest agent"
	depends=""
	options=""

	mkdir -p "$subpkgdir"/usr/bin
	mv "$pkgdir"/usr/bin/qemu-ga "$subpkgdir"/usr/bin/
}

_module() {
	local _mod=${subpkgname#qemu-}
	local _class=${_mod%%-*}
	local _m=${_mod#*-}
	pkgdesc="Qemu $_m $_class module"
	case "$_mod" in
		ui-egl-headless|ui-gtk|ui-sdl|ui-spice-core) depends="qemu-ui-opengl";;
		hw-display-qxl) depends="qemu-ui-spice-core";;
		hw-display-virtio-vga|hw-display-virtio-gpu-gl) depends="qemu-hw-display-virtio-gpu";;
	esac

	mkdir -p "$subpkgdir"/usr/lib/qemu
	mv "$pkgdir"/usr/lib/qemu/$_mod.so \
		"$subpkgdir"/usr/lib/qemu/
}

_all_modules() {
	pkgdesc="Meta package for all qemu modules"
	local _i
	for _i in $_modules; do
		depends="$depends qemu-$_i"
	done
	mkdir -p "$subpkgdir"
}

bridgehelper() {
	pkgdesc="QEMU SUID helper for bridged networking"
	install_if="$pkgname=$pkgver-r$pkgrel"

	amove usr/lib/qemu/qemu-bridge-helper \
		etc/qemu/bridge.conf
}

sha512sums="
cbf2e43d54eafe776dd8245a91ff3c28bbe6206b62205addb25b49ffaac79cefc49c9df082c28aedc17ffc4a67db6352fc7a97895887ccbbb1ce198981e242b4  qemu-9.1.1.tar.xz
b392f229e631d149d28eb952dcd507d9e5b6975cbba123fd3dab10860fa1936d5035d8e266926652acc1d7cde6874c440beccd33d729bf346769d2c138ebbc01  0006-linux-user-signal.c-define-__SIGRTMIN-MAX-for-non-GN.patch
2c6b3b22877674f870958bb0c74ad85c814f01c98fb123142b1ce77d89adf5c08626e6eade7f627090a53b48f5cebe2a535547804345648cff91dd66f90c2d5b  xattr_size_max.patch
7672a3518050f275219920f2cb088f6991ac810dba077856129d779fdf45a3e8c0302c8ca4aa58c0c38e44af80f56404006b3f250e4921fb364cd6fe7149e6ea  MAP_SYNC-fix.patch
54d26c3c44730fbd2a155431558fba6a1a3f25d8c057a8e5b8b0d802cb2b6c8a12545a16069fff1b9888a15d6cb087e9750d5e2c310dfc1a3fc756509d3d963e  fix-sockios-header.patch
3e36d752fc2d7eab65568b731c3a21ed534fbfeee43ff8faf4aff95bbe29b74cd9d7013c28f37b86cfbb3ec1e189d5deef36017c06f20b5c732ab50a36b39f51  guest-agent-shutdown.patch
d5b4626193fa9b7c687a649aa5ea37d8a74fd2e556a66a71e31af618a0990e144beae253b82b89efd8a798102bcab59cf1a61a76029afcdb0bc5ed58fb40493f  lfs64.patch
7a6340df8aa28811af20cd23b98ba95fc8072d4d4d3a2d497604386396892cf26716d0755821e47d02c8eded203133d7dde100537c117e2a047179e4f93883cf  musl-initialise-msghdr.patch
7df4b0979d11fb0b7d2dbb073d7249677b0f51381dfbeb1bec2e44d29dd6e1d752468d7f9fb5b42deed6bdf184e81358e7b6dc54b36db326f3336cd6121a1a60  fix-strerrorname_np.patch
75979455abcd9d9f25a966d829d578a06691163e297247c045ce67f94ebc916850b7be1080024a9db6bba9e3f7b88a8cc486f364fb7b028804862bc8634f00e4  liburing.patch
fb9f430cfba6bc1d4a37d1b0af62b0277b17fd7d712264debecd7347a36b23e23a995e35af8f4910fabde577ec13160eda757209db768a20fd1fb1d4d310d1f4  0001-util-util-cpuinfo-riscv.c-fix-riscv64-build-on-musl-.patch
d90c034cae3f9097466854ed1a9f32ab4b02089fcdf7320e8f4da13b2b1ff65067233f48809911485e4431d7ec1a22448b934121bc9522a2dc489009e87e2b1f  qemu-guest-agent.confd
1cd24c2444c5935a763c501af2b0da31635aad9cf62e55416d6477fcec153cddbe7de205d99616def11b085e0dd366ba22463d2270f831d884edbc307c7864a6  qemu-guest-agent.initd
9b7a89b20fcf737832cb7b4d5dc7d8301dd88169cbe5339eda69fbb51c2e537d8cb9ec7cf37600899e734209e63410d50d0821bce97e401421db39c294d97be2  80-kvm.rules
749efa2e764006555b4fd3a8e2f6d1118ad2ea4d45acf99104a41a93cfe66dc9685f72027c17d8211e5716246c2a52322c962cf4b73b27541b69393cd57f53bb  bridge.conf
"
